package com.bankcomm.luafuction;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Stack;

import org.keplerproject.luajava.LuaException;
import org.keplerproject.luajava.LuaObject;
import org.keplerproject.luajava.LuaState;

import android.R.integer;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.widget.AbsoluteLayout;
import android.widget.AbsoluteLayout.LayoutParams;

import com.bankcomm.common.ConfigManager;
import com.rytong.tools.animation.EmpAnimation;
import com.rytong.tools.ui.Component;
import com.rytong.tools.ui.LPLabel;
import com.rytong.tools.ui.LPLayout;
import com.rytong.tools.utils.Utils;

public class LuaAnimation {
	final public int LINEAR = 0;
    final public int EASE_IN = 1;
    final public int EASE_OUT = 2;
    final public int EASE_INOUT = 3;
    
    // 控件与动画的匹配集合
    private HashMap cAndO_;
    private ArrayList alValue_;
    
    //动画寄主与位置信息
    private Hashtable<Object, Component> mParasitic = new Hashtable<Object, Component>();
    private float mLocationX = 0;
    private float mLocationY = 0;
    private float mLocationW = 0;
    private float mLocationH = 0;

    public LuaAnimation() {
        // TODO Auto-generated constructor stub
        try {
            Component.LUASTATE.pushObjectValue(this);
            Component.LUASTATE.setGlobal("luaanimation");
            final String luahead = "animation = {}; ";
            final String luafc1 = "function animation:newFrames(table)   local a1 = luaanimation:newFrames(table); return a1; end;";
            final String luafc2 = "function animation:setDuration(object,duration) luaanimation:setDuration(object,duration); end;";
            final String luafc3 = "function animation:play(repeatCount) luaanimation:play(repeatCount); end;";
            final String luafc4 = "function animation:stop(object) luaanimation:stop(object); end;";
            final String luafc5 = "function animation:setStartListener(object,func) luaanimation:setStartListener(object,func); end;";
            final String luafc6 = "function animation:setStopListener(object,func) luaanimation:setStopListener(object,func); end;";
            final String luafc7 = "function animation:setRepeatCount(object,repeatCount) luaanimation:setRepeatCount(object,repeatCount); end;";
            final String luafc8 = "function animation:add(object,superView) luaanimation:add(object,superView); end;";
            final String luafc9 = "function animation:setCurve(object,curve) luaanimation:setCurve(object,curve); end;";
            final String luafc10 = "function animation:new(func) local a1 = luaanimation:newAnimation(func); return a1; end;";
            final String luafc11 = "function animation:setFrame(object,frame) luaanimation:setFrame(object,frame); end;";
            Component.LUASTATE.gc(LuaState.LUA_GCCOLLECT, 0);
            Component.LUASTATE.LdoString(luahead.concat(luafc1).concat(luafc2).concat(luafc3).concat(luafc4)
                    .concat(luafc5).concat(luafc6).concat(luafc7).concat(luafc10).concat(luafc11).concat(luafc8).concat(luafc9));

        } catch (Exception e) {
            Utils.printException(e);
        }
    }

    public void setFrame(Object object, LuaObject frame) {
        frame.push();
        // 循环读取table中的属性值
        Component.LUASTATE.pushNil();
//        ArrayList alValue = new ArrayList(2);
        String keyString = "";
        String valueString = "";
        while (Component.LUASTATE.next(-2) != 0) {
            keyString = "";
            if (Component.LUASTATE.type(-2) == Component.LUASTATE.LUA_TNUMBER) {
                keyString = Double.toString(Component.LUASTATE.toNumber(-2));
            } else if (Component.LUASTATE.type(-2) == Component.LUASTATE.LUA_TSTRING) {
                keyString = Component.LUASTATE.toString(-2);
            }
            valueString = "";
            if (Component.LUASTATE.type(-1) == Component.LUASTATE.LUA_TNUMBER) {
                valueString = Double.toString(Component.LUASTATE.toNumber(-1));
            } else if (Component.LUASTATE.type(-1) == Component.LUASTATE.LUA_TSTRING) {
                valueString = Component.LUASTATE.toString(-1);
            } else if (Component.LUASTATE.type(-1) == Component.LUASTATE.LUA_TTABLE) {
            }
            
            keyString = keyString.trim();
            final float value = Float.valueOf(valueString.trim());
            if(keyString.equalsIgnoreCase("x")){
            	
            	mLocationX = Utils.getScaledValueX(value);
            } else if(keyString.equalsIgnoreCase("y")){
            	
            	mLocationY = Utils.getScaledValueY(value);
            } else if(keyString.equalsIgnoreCase("width")){
            	
            	mLocationW = Utils.getScaledValueX(value);
            } else if(keyString.equalsIgnoreCase("height")){
            	
            	mLocationH = Utils.getScaledValueY(value);
            }
//            alValue.add(valueString);
            Component.LUASTATE.pop(1);
        }
        Component.LUASTATE.pop(2);
        
        float x = mLocationX;
        float y = mLocationY;
        float w = mLocationW;
        float h = mLocationH;

//        float x = Float.valueOf(alValue.get(0).toString());
//        float y = Float.valueOf(alValue.get(1).toString());
//        float w = Float.valueOf(alValue.get(2).toString());
//        float h = Float.valueOf(alValue.get(3).toString());

//        x = Utils.getScaledValueX(x);
//        y = Utils.getScaledValueY(y);
//        w = Utils.getScaledValueX(w);
//        h = Utils.getScaledValueY(h);

        if (object instanceof AnimationDrawable) {
        	
//            AnimationDrawable ad = (AnimationDrawable) object;
//            if (null != cAndO_) {
//                Component temp = (Component) cAndO_.get(ad);
//                if (null != temp) {
//                    LayoutParams lp = (LayoutParams) temp.getLayoutParams();
//                    if (null == lp)
//                        lp = new LayoutParams((int) w, (int) h, (int) x, (int) y);
//                    // 此坐标只是动画针对控件本身的定位，由于启用setBounds好像没有效果，所以用改变控件自身
//                    // 布局的方法来达到效果
//                    lp.x += (int) x;
//                    lp.y += (int) y;
//                    lp.width = (int) w;
//                    lp.height = (int) h;
//                }
//            }
        } else if (object instanceof Animation) {
            Animation animation = (Animation) object;
            animation.initialize((int) x, (int) y, (int) w, (int) h);
        }
    }

    /**
     * 在动画结束后调用该监听方法
     * 
     * @param function
     */
    public void setStopListener(Object object, LuaObject function) {
        try {
            Object[] args = new Object[1];
            args[0] = object;
            function.call(args, 0);
        } catch (LuaException e) {
            // TODO Auto-generated catch block
            Utils.printException(e);
        }
    }

    /**
     * function方法，该方法内为需要动画显示的目标设置
     * 
     * @param function
     * @return
     */
    public Object newAnimation(LuaObject function) {
        EmpAnimation animation = new EmpAnimation();
        try {
            function.call(null);
        } catch (LuaException e) {
            // TODO Auto-generated catch block
            Utils.printException(e);
        }
        return animation;
    }

    /**
     * 在动画开始前调用该监听方法
     * 
     * @param function
     */
    public void setStartListener(Object object, LuaObject function) {
        try {
            Object[] args = new Object[1];
            args[0] = object;
            function.call(args, 0);
        } catch (LuaException e) {
            // TODO Auto-generated catch block
            Utils.printException(e);
        }
    }

    /**
     * object：动画对象 curve：动画展示速度效果
     * 
     * @param object
     * @param curve
     */
    public void setCurve(Object object, Object curveObject) {
        if (object instanceof Animation) {
            Animation animation = (Animation) object;
            int curve = Integer.parseInt(curveObject.toString());
            switch (curve) {
            case LINEAR:
                // 动画匀速播放
            	animation.setInterpolator(new LinearInterpolator());
                break;
            case EASE_IN:
                // 播放速度先慢后快
            	animation.setInterpolator(new AccelerateInterpolator());
                break;
            case EASE_OUT:
                // 播放速度先快后慢
            	animation.setInterpolator(new DecelerateInterpolator());
                break;
            case EASE_INOUT:
                // 播放速度先慢再快再慢
            	animation.setInterpolator(new AccelerateDecelerateInterpolator());
            default:
                break;
            }
        }
    }

    /**
     * 
     * @param object
     * @param view
     *            object ：动画对象 superView：负责展示动画的控件
     */
	@SuppressWarnings("deprecation")
	public void add(Object object, Component component) {
		
		if(null == object){
			
			return ;
		}
		
		removeAnimation(object);
		if (object instanceof AnimationDrawable) {
			
			if(component instanceof LPLayout){
				LayoutParams l = new AbsoluteLayout.LayoutParams((int)mLocationW, (int)mLocationH, (int)mLocationX, (int)mLocationY);
				LPLayout parasitic = new LPLayout();
				parasitic.initRealView(component.getActivity(), "");
				parasitic.setLayoutParams(l);
				parasitic.setBackgroundDrawable((AnimationDrawable)object);
				
				component.addView(parasitic);
				parasitic.setParent(component);
				
				mParasitic.put(object, parasitic);
			} else {
				component.setDrawBorder_(false);
				component.setBackgroundDrawable((AnimationDrawable) object);
			}
			
//			if (null == cAndO_)
//				cAndO_ = new HashMap<AnimationDrawable, Component>();
//			component.setDrawBorder_(false);
//			component.setBackgroundDrawable((AnimationDrawable) object);
//			cAndO_.put((AnimationDrawable) object, component);
		} else if (object instanceof Animation) {
			component.setAnimation((Animation) object);
		}
	}
	
	/**
	 * 移除动画
	 * @param object
	 */
	private void removeAnimation(Object object) { 

		final Component parasiticLayout = mParasitic.get(object);
		if (null != parasiticLayout && null != parasiticLayout.parentComponent_) {

			final Component parent = parasiticLayout.parentComponent_;
			parent.removeView(parasiticLayout);

			mParasitic.remove(object);
		}
	}

    /**
     * 
     * @param object
     *            object：动画对象
     */
    public void stop(Object object) {
        if (object instanceof AnimationDrawable) {
            ((AnimationDrawable) object).stop();
        } else if (object instanceof Animation) {
            ((Animation) object).cancel();
        }
        
        removeAnimation(object);
    }

    /**
     * object：动画对象 repeatCount：重复播放次数。如果小于等于1则默认只播放一次
     * 
     * @param object
     * @param repeatCount
     */
    public void setRepeatCount(Object object, int repeatCount) {
        if (object instanceof AnimationDrawable) {
            AnimationDrawable ad = (AnimationDrawable) object;
            if(repeatCount == -1){
            	
            	ad.setOneShot(false);
            } else if(repeatCount > 0){
            	
            	int delay = 0;
                for (int i = 0; i < ad.getNumberOfFrames(); i++) {
                	
                	delay += ad.getDuration(i);
                }
            	repeatAnimation(ad, repeatCount, delay);
            } else {
            	
            	ad.setOneShot(true);
            }
        } else if (object instanceof Animation) {
            if (repeatCount <= 1)
                ((Animation) object).setRepeatCount(1);
            else
                ((Animation) object).setRepeatCount(repeatCount);
        }
    }
    
	private void repeatAnimation(final AnimationDrawable animation, final int repeatNumber, final int delay) {

		if (repeatNumber < 1) {

			removeAnimation(animation);
			return;
		}
		
		final Handler handler = new Handler();
		handler.postDelayed(new Runnable() {

			@Override
			public void run() {

				animation.stop();
				animation.start();
				repeatAnimation(animation, repeatNumber-1, delay);
			}
		}, delay);
	}

    /**
     * 
     * @param duration
     *            duration动画播放时常
     */
    public void setDuration(Object object, int duration) {
        duration = duration * 1000;
        if (object instanceof AnimationDrawable) {
            // 该duration参数指的是整个动画一次性播放的时常，且以秒为单位，所以需将其毫秒划，并加以分割。
            AnimationDrawable ad = (AnimationDrawable) object;
            if (null != alValue_ && !alValue_.isEmpty()) {
                // 得到动画的帧总数
                int size = alValue_.size();
                // 计算出每帧的播放时常
                duration = duration / size;

                Bitmap bitmap;
                String pngName = "";
                // 设置每帧图片的显示时间
                for (int i = 0; i < size; i++) {
                    pngName = ((String) alValue_.get(i)).trim();
                    bitmap = Utils.getBitmapFromResources(ConfigManager.currentView_, pngName);
                    ad.addFrame(new BitmapDrawable(bitmap), duration);
                }
            }
        } else if (object instanceof Animation) {
            ((Animation) object).setDuration(duration);
        }
    }

    /**
     * 
     * @param repeatCount
     *            object：动画对象
     */
    public void play(final Object object) {
        // TODO Auto-generated method stub
        if (object instanceof AnimationDrawable) {
            ((AnimationDrawable) object).start();
        } else if (object instanceof Animation) {
            ((Animation) object).start();
        }
    }

    /**
     * 创建动画
     * 
     * @param fameTable
     *            名称 table对象，所有帧图片名称
     */
    public Object newFrames(LuaObject fameTable) {
        fameTable.push();
        // 循环读取table中的属性值
        Component.LUASTATE.pushNil();
        ArrayList alKey = new ArrayList(2);
        alValue_ = new ArrayList(2);
        String keyString = "";
        String valueString = "";
        while (Component.LUASTATE.next(-2) != 0) {
            keyString = "";
            if (Component.LUASTATE.type(-2) == Component.LUASTATE.LUA_TNUMBER) {
                keyString = Double.toString(Component.LUASTATE.toNumber(-2));
            } else if (Component.LUASTATE.type(-2) == Component.LUASTATE.LUA_TSTRING) {
                keyString = Component.LUASTATE.toString(-2);
            }
            valueString = "";
            if (Component.LUASTATE.type(-1) == Component.LUASTATE.LUA_TNUMBER) {
                valueString = Double.toString(Component.LUASTATE.toNumber(-1));
            } else if (Component.LUASTATE.type(-1) == Component.LUASTATE.LUA_TSTRING) {
                valueString = Component.LUASTATE.toString(-1);
            } else if (Component.LUASTATE.type(-1) == Component.LUASTATE.LUA_TTABLE) {
            }

            alValue_.add(valueString);
            alKey.add(keyString);
            Component.LUASTATE.pop(1);
        }
        Component.LUASTATE.pop(2);

        AnimationDrawable ad = new AnimationDrawable();
        return ad;
    }
}
